﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using MySql.Data.MySqlClient;
using DateBaseConnectionPool;

namespace TestMySqlConnetPoll
{
    public struct objTongJiReport
    {
        public int year;
        public int month;
        public Int16 totalCount;
        public Int16 totolTime;

        public objTongJiReport(int y, int m, int tc, int tt)
        {
            year = y;
            month = m;
            totalCount = (Int16)tc;
            totolTime = (Int16)tt;
        }
    }
    public struct objTongJiKey
    {
        public int type;        //统计类型
        public string DevName;  //统计设备名称

        public objTongJiKey(int devtype, string IndevName)
        {
            type = devtype;
            DevName = IndevName;
        }
    }
    public class TongJiTable
    {
        #region 变量定义 统计报表
        
        public bool Ready_TimeList = false;
        public bool Ready_ValueList = false;
        public int ErrorFlag = 0;
        public List<int> TimeList = new List<int>();
        
        /// <summary>
        /// 以设备号做键值
        /// </summary>
        public Dictionary<objTongJiKey, List<objTongJiReport>> ValueList = new Dictionary<objTongJiKey, List<objTongJiReport>>();

        public struct ThreadObj
        {
            public string TypeName;
            public int Year;
            public int month;
        }

        public void ReadTimeList(string TypeName)
        {
            ErrorFlag = 0;
            Ready_TimeList = false;
            TimeList.Clear();
            ThreadObj obj = new ThreadObj();
            obj.TypeName = TypeName;
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadReadTimeList),obj);
        }

        public void ReadValueList(string TypeName, int year,int month)
        {
            ErrorFlag = 0;
            Ready_ValueList = false;
            ValueList.Clear();
            ThreadObj obj = new ThreadObj();
            obj.TypeName = TypeName;
            obj.Year = year;
            obj.month = month;
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadReadValueList),obj);
        }
        /// <summary>
        /// 获得某个设备一年的统计次数和实际
        /// </summary>
        /// <param name="TypeName"></param>
        /// <param name="DevName"></param>
        /// <param name="month"></param>
        /// <param name="AllCount"></param>
        /// <param name="AllTime"></param>
        public List<objTongJiReport> GetDevCount(string TypeName, int year)
        {
            int devtype = c_Device.GetTongJiType(TypeName);
            List<objTongJiReport> li = new List<objTongJiReport>();
            for (int i = 1; i <= 12; i++)
            {
                foreach (objTongJiKey key in ValueList.Keys)
                {
                    if (key.type == devtype)
                    {
                        objTongJiReport value = new objTongJiReport();
                        value.month = i;
                        value.year = year;
                        foreach (objTongJiReport devkey in ValueList[key])
                        {
                            if (devkey.month == i && devkey.year == year)
                            {                                
                                value.totalCount += devkey.totalCount;
                                value.totolTime += devkey.totolTime; 
                            }
                        }
                        li.Add(value);
                    }
                }
            }
            return li;
        }


        #endregion
        #region 统计类报表
        private Mutex keyMutex = new Mutex();
        static private int keykey = 0;
        public bool InsertDateTable(byte DevType, Int16 DevNo, objTongJiReport obj)
        {
            bool tmpFlag = false;
            string TableName = "tongjireport";
            if (TableName == "") return tmpFlag;
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    tmpFlag = false;
                }
                
                if (con != null)
                {
                    //首先需删除原有的记录
                    StringBuilder dels = new StringBuilder();
                    dels.Append(string.Format("delete from {0} where year = {1} and month = {2}  ", TableName, obj.year, obj.month));
                    dels.Append(string.Format(" and dev_type = {1} and dev_no = {2}", TableName, DevType, DevNo));
                    MySqlCommand delcommand = new MySqlCommand(dels.ToString(), con);
                    try
                    {
                        delcommand.ExecuteNonQuery();
                    }
                    catch (MySqlException ex)
                    {
                        //写异常日记
                        tmpFlag = false;       //写入失败
                    }

                    //再插入数据
                    StringBuilder InsertStatement = new StringBuilder();
                    InsertStatement.Append(string.Format("insert into {0}(dev_type,dev_no,year,month,totalcount,totaltime) ", TableName));

                    InsertStatement.Append(" values(?dev_type,?dev_no,?year,?month,?totalcount,?totaltime)");

                    MySqlCommand InsertCommand = new MySqlCommand(InsertStatement.ToString(), con);
                    InsertCommand.Parameters.Add(new MySqlParameter("?dev_type", MySqlDbType.Byte)).Value = (byte)DevType;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dev_no", MySqlDbType.Int16)).Value = DevNo;
                    InsertCommand.Parameters.Add(new MySqlParameter("?year", MySqlDbType.Int32)).Value = obj.year;
                    InsertCommand.Parameters.Add(new MySqlParameter("?month", MySqlDbType.Byte)).Value = obj.month;
                    InsertCommand.Parameters.Add(new MySqlParameter("?totalcount", MySqlDbType.Int16)).Value = obj.totalCount;
                    InsertCommand.Parameters.Add(new MySqlParameter("?totaltime", MySqlDbType.Int16)).Value = obj.totolTime;

                    try
                    {
                        int k = InsertCommand.ExecuteNonQuery();
                        if (k == 1) tmpFlag = true;        //写入成功
                        else tmpFlag = false;              //写入失败
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                        tmpFlag = false;       //写入失败
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                    }
                }
            }
            return tmpFlag;
        }

        /// <summary>
        /// 只要有操作，就先清除记录，每次从新取记录
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="DevType"></param>
        /// <returns></returns>
        private void ThreadReadTimeList(object o)
        {
            ThreadObj obj = (ThreadObj)o;
            string TypeName = obj.TypeName;
            TimeList.Clear();
            string TableName = "TongJiReport";
            int DevType = c_Device.GetTongJiType(TypeName);
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    ErrorFlag = 1;
                }
                if (con != null)
                {
                    StringBuilder SelectStatement = new StringBuilder();

                    SelectStatement.Append(string.Format("select year from {0} where dev_type = {1}", TableName, DevType));

                    try
                    {
                        MySqlCommand selectCommand = new MySqlCommand(SelectStatement.ToString(), con);
                        selectCommand.CommandTimeout = 120;   //120s操作超时

                        MySqlDataReader read = selectCommand.ExecuteReader();
                        while (read.Read())
                        {
                            int t = read.GetInt32(read.GetOrdinal("year"));
                            if (TimeList.Contains(t)) { }
                            else TimeList.Add(t);     //加入到时间列表里面
                        }
                        read.Close();
                        Ready_TimeList = true;
                    }
                    catch (MySqlException e)
                    {
                        //写错误日志
                        ErrorFlag = 2;
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        //写错误日志
                        ErrorFlag = 3;
                    }
                }
                else ErrorFlag = 6;
            }
            else ErrorFlag = 7;
        }

        /// <summary>
        /// 只要有取数据操作，就先清除缓冲区，每次重新取记录
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="DevType"></param>
        /// <param name="Year"></param>
        /// <returns></returns>
        private void ThreadReadValueList(object o)
        {
            ThreadObj obj = (ThreadObj)o;
            string TypeName = obj.TypeName;
            int Year = obj.Year;
            int month = obj.month;
            int DevType = c_Device.GetTongJiType(TypeName);
            string TableName = "TongJiReport";
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    ErrorFlag = 1;
                }
                if (con != null)
                {
                    StringBuilder SelectStatement = new StringBuilder();

                    if (month == 0)
                    {
                        SelectStatement.Append(string.Format("select month,dev_no,totalcount,totaltime from {0} where year = {1} and  dev_type = {2} ", TableName, Year, DevType));
                    }
                    else
                    {
                        SelectStatement.Append(string.Format("select dev_no,totalcount,totaltime from {0} where year = {1} and month = {2} and  dev_type = {3} ", TableName, Year,month, DevType));
                    }
                    try
                    {
                        MySqlCommand selectCommand = new MySqlCommand(SelectStatement.ToString(), con);
                        selectCommand.CommandTimeout = 120;   //120s操作超时

                        MySqlDataReader read = selectCommand.ExecuteReader();
                        while (read.Read())
                        {
                            objTongJiReport t = new objTongJiReport();
                            t.year = Year;
                            if (month == 0)
                            {
                                t.month = read.GetByte(read.GetOrdinal("month"));
                            }
                            else t.month = month;

                            Int16 devno = read.GetInt16(read.GetOrdinal("dev_no"));
                            t.totalCount = read.GetInt16(read.GetOrdinal("totalcount"));
                            t.totolTime = read.GetInt16(read.GetOrdinal("totaltime"));
                            objTongJiKey tjkey = new objTongJiKey();
                            string DevName = c_Device.GetTongJiDevName(DevType, devno);
                            tjkey.type = DevType;
                            tjkey.DevName = DevName;

                            if (ValueList.Keys.Contains(tjkey))
                            {
                                ValueList[tjkey].Add(t);
                            }
                            else
                            {
                                List<objTongJiReport> k = new List<objTongJiReport>();
                                k.Add(t);
                                ValueList.Add(tjkey, k);
                            }
                        }
                        read.Close();
                        if (ErrorFlag == 0) Ready_ValueList = true;
                    }
                    catch (MySqlException e)
                    {
                        //写错误日志
                        ErrorFlag = 3;
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        //写错误日志
                        ErrorFlag = 4;
                    }
                }
                else ErrorFlag = 6;
            }
            else ErrorFlag = 7;
        }
        #endregion
    }
}
